/*-*
 * FILENAME  :
 *    $HeadURL$
 *
 * STATUS  :
 *    $Revision$
 *
 *    $Author$
 *    $Date$
 *  
 *    
 * Copyright (c) 2011 Gonalge Ltda. All rights reserved.
 *
 ****************************************************************/

package org.gonalge.arbolrojonegro.presentacion;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import org.gonalge.arbolrojonegro.dto.Nodo;
import org.gonalge.arbolrojonegro.negocio.Lista;
import org.gonalge.arbolrojonegro.type.CasoArbol;
import org.gonalge.arbolrojonegro.type.ColorNodo;
import org.gonalge.arbolrojonegro.util.FormUtils;

/**
 * 
 * @author Geremias Gonzalez
 */
public class PintarArbol extends Canvas {

    /**
     * 
     */
    private static final long serialVersionUID = -5877519963894624334L;

    private Nodo arbol;

    private Lista recorrido = new Lista();

    private int indexRecorrido = 0;

    private int elemento;

    private final BufferedImage fondo;

    private final Color colorRojo = FormUtils.getColorTitulo();

    private final Color colorNegro = Color.BLACK;

    public PintarArbol() {
        setSize(2000, 1000);
        fondo = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
    }

    public void pintar() {
        paint(getGraphics());

    }

    public void update(Graphics2D g) {
        paint(getGraphics());
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D graphics2 = fondo.createGraphics();
        graphics2.setColor(FormUtils.getColorFondo());
        graphics2.fillRect(0, 0, getWidth(), getHeight());
        Imprimir(graphics2, arbol);
        g.drawImage(fondo, 0, 0, this);
    }

    private void Imprimir(Graphics g, Nodo r) {
        g.setFont(g.getFont().deriveFont(23, 13));
        g.setColor(Color.BLACK);
        if (r != null) {
            if (r.getRD() == null && r.getRI() == null) {
                g.setColor(buscarColor(r.getColor()));
                g.fillOval(r.getX(), r.getY(), 21, 21);
                g.setColor(Color.BLACK);
                g.drawOval(r.getX(), r.getY(), 21, 21);
                // -------------------------
                g.drawLine(r.getX() - 7, r.getY() + 29, r.getX() - 15, r.getY() + 50);
                g.drawLine(r.getX() - 7, r.getY() + 29, r.getX() + 2, r.getY() + 50);
                g.drawLine(r.getX() - 15, r.getY() + 50, r.getX() + 2, r.getY() + 50);
                // ------------------------------
                g.drawLine(r.getX() + 25, r.getY() + 29, r.getX() + 15, r.getY() + 50);
                g.drawLine(r.getX() + 25, r.getY() + 29, r.getX() + 34, r.getY() + 50);
                g.drawLine(r.getX() + 15, r.getY() + 50, r.getX() + 34, r.getY() + 50);
                // ------------------------------------------
                g.drawLine(r.getX() + 10, r.getY() + 20, r.getX() - 5, r.getY() + 28);
                g.drawLine(r.getX() + 10, r.getY() + 20, r.getX() + 25, r.getY() + 28);
                g.setColor(Color.YELLOW);
                g.drawString("" + r.getEle(), r.getX() + 5, r.getY());
            } else {
                if (r.getRI() != null) {
                    Imprimir(g, r.getRI());
                    g.setColor(buscarColor(r.getColor()));
                    g.fillOval(r.getX(), r.getY(), 21, 21);
                    g.setColor(Color.BLACK);
                    g.drawOval(r.getX(), r.getY(), 21, 21);
                    g.drawLine(r.getX() + 10, r.getY() + 20, r.getRI().getX() + 10, r.getRI().getY());
                    g.setColor(Color.YELLOW);
                    g.drawString("" + r.getEle(), r.getX() + 5, r.getY());
                } else {
                    g.drawLine(r.getX() - 7, r.getY() + 29, r.getX() - 15, r.getY() + 50);
                    g.drawLine(r.getX() - 7, r.getY() + 29, r.getX() + 2, r.getY() + 50);
                    g.drawLine(r.getX() - 15, r.getY() + 50, r.getX() + 2, r.getY() + 50);
                    g.drawLine(r.getX() + 10, r.getY() + 20, r.getX() - 5, r.getY() + 28);
                }
                if (r.getRD() != null) {
                    g.setColor(buscarColor(r.getColor()));
                    g.fillOval(r.getX(), r.getY(), 21, 21);
                    g.setColor(Color.BLACK);
                    g.drawOval(r.getX(), r.getY(), 21, 21);
                    g.drawLine(r.getX() + 10, r.getY() + 20, r.getRD().getX() + 10, r.getRD().getY() + 10);
                    g.setColor(Color.YELLOW);
                    g.drawString("" + r.getEle(), r.getX() + 5, r.getY());
                    Imprimir(g, r.getRD());
                } else {
                    g.setColor(Color.BLACK);
                    g.drawLine(r.getX() + 25, r.getY() + 29, r.getX() + 15, r.getY() + 50);
                    g.drawLine(r.getX() + 25, r.getY() + 29, r.getX() + 34, r.getY() + 50);
                    g.drawLine(r.getX() + 15, r.getY() + 50, r.getX() + 34, r.getY() + 50);
                    g.drawLine(r.getX() + 10, r.getY() + 20, r.getX() + 25, r.getY() + 28);
                }
                g.setFont(g.getFont().deriveFont(23, 13));

            }
        }
    }

    public int pintarCamino(Graphics g) {
        g.setColor(colorRojo);
        g.setFont(g.getFont().deriveFont(23, 13));
        Nodo r = (Nodo) recorrido.consultar(indexRecorrido);
        String s = "";
        s = (r.getEle() > elemento) ? "<" : ">";
        g.drawString(elemento + " " + s, r.getX() + 5, r.getY() - 15);
        return r.getEle();
    }

    public int pintarCamino() {
        int ele1 = 0;
        if (indexRecorrido < recorrido.getSize()) {
            ele1 = pintarCamino(fondo.getGraphics());
            getGraphics().drawImage(fondo, 0, 0, this);
        }
        return ele1;
    }

    public void pintarCam() {
        pintarCamino(fondo.getGraphics());
    }

    public void setLc(Lista Lc, int e) {
        this.recorrido = Lc;
        this.elemento = e;
    }

    public void SuArbolP2() {
        SuArbolP2(fondo.getGraphics());
        getGraphics().drawImage(fondo, 0, 0, this);
    }

    private Color buscarColor(ColorNodo color) {
        return (color == ColorNodo.NEGRO) ? colorNegro : colorRojo;
    }

    private void SuArbolP2(Graphics g) {
        g.setColor(Color.BLUE);
        g.drawString("B", arbol.getX() + 10, arbol.getY() - 15);
        g.drawString("C", arbol.getRD().getX() + 10, arbol.getRD().getY() - 15);
        g.drawString("A", arbol.getRI().getX() + 10, arbol.getRI().getY() - 15);
    }

    public void pintarSubArbol(CasoArbol caso) {
        pintarSubArbol(fondo.getGraphics(), caso);
        getGraphics().drawImage(fondo, 0, 0, this);
    }

    private void pintarSubArbol(Graphics g, CasoArbol caso) {
        g.setColor(Color.BLUE);
        switch (caso) {
            case CASO_UNO:
                g.drawString("A", arbol.getX() + 10, arbol.getY() - 15);
                g.drawString("B", arbol.getRD().getX() + 10, arbol.getRD().getY() - 15);
                g.drawString("C", arbol.getRD().getRD().getX() + 10, arbol.getRD().getRD().getY() - 15);
                g.setColor(Color.BLACK);
                g.drawString("e", arbol.getX() - 15, arbol.getY() + 15);
                g.drawString("e1", arbol.getRD().getX() - 15, arbol.getRD().getY() + 15);
                g.drawString("e2", arbol.getRD().getRD().getX() - 15, arbol.getRD().getRD().getY() + 15);
                break;
            case CASO_DOS:
                g.drawString("A", arbol.getX() + 10, arbol.getY() - 15);
                g.drawString("C", arbol.getRD().getX() + 10, arbol.getRD().getY() - 15);
                g.drawString("B", arbol.getRD().getRI().getX() + 10, arbol.getRD().getRI().getY() - 15);
                g.setColor(Color.BLACK);
                g.drawString("e", arbol.getX() - 15, arbol.getY() + 15);
                g.drawString("e1", arbol.getRD().getX() - 15, arbol.getRD().getY() + 15);
                g.drawString("e2", arbol.getRD().getRI().getX() - 15, arbol.getRD().getRI().getY() + 15);
                break;
            case CASO_TRES:
                g.drawString("C", arbol.getX() + 10, arbol.getY() - 15);
                g.drawString("B", arbol.getRI().getX() + 10, arbol.getRI().getY() - 15);
                g.drawString("A", arbol.getRI().getRI().getX() + 10, arbol.getRI().getRI().getY() - 15);
                g.setColor(Color.BLACK);
                g.drawString("e", arbol.getX() - 15, arbol.getY() + 15);
                g.drawString("e1", arbol.getRI().getX() - 15, arbol.getRI().getY() + 15);
                g.drawString("e2", arbol.getRI().getRI().getX() - 15, arbol.getRI().getRI().getY() + 15);
                break;
            case CASO_CUATRO:
                g.drawString("C", arbol.getX() + 10, arbol.getY() - 15);
                g.drawString("A", arbol.getRI().getX() + 10, arbol.getRI().getY() - 15);
                g.drawString("B", arbol.getRI().getRD().getX() + 10, arbol.getRI().getRD().getY() - 15);
                g.setColor(Color.BLACK);
                g.drawString("e", arbol.getX() - 15, arbol.getY() + 15);
                g.drawString("e1", arbol.getRI().getX() - 15, arbol.getRI().getY() + 15);
                g.drawString("e2", arbol.getRI().getRD().getX() - 15, arbol.getRI().getRD().getY() + 15);
                break;
        }
    }

    private Nodo buscar(Nodo r, int e) {
        if (r.getEle() != e) {
            if (r.getEle() < e)
                r = buscar(r.getRD(), e);
            else
                r = buscar(r.getRI(), e);
        }
        return r;
    }

    public void pintarCaso2() {
        pintarCaso2(fondo.getGraphics(), arbol);
        getGraphics().drawImage(fondo, 0, 0, this);
    }

    private void pintarCaso2(Graphics g, Nodo t) {
        g.setColor(Color.BLACK);
        if (t != null) {
            if (t.getRD() != null) {
                if (t.getRD().getColor() == ColorNodo.ROJO && t.getRD().getRD() != null) {
                    if (t.getRD().getRD().getColor() == ColorNodo.ROJO) {
                        g.drawString("e", t.getX() - 15, t.getY() + 15);
                        g.drawString("e1", t.getRD().getX() - 15, t.getRD().getY() + 15);
                        g.drawString("e2", t.getRD().getRD().getX() - 15, t.getRD().getRD().getY() + 15);
                    }

                }
                if (t.getRD().getColor() == ColorNodo.ROJO && t.getRD().getRI() != null) {
                    if (t.getRD().getRI().getColor() == ColorNodo.ROJO) {
                        g.drawString("e", t.getX() - 15, t.getY() + 15);
                        g.drawString("e1", t.getRD().getX() - 15, t.getRD().getY() + 15);
                        g.drawString("e2", t.getRD().getRI().getX() - 15, t.getRD().getRI().getY() + 15);
                    }

                }

            }

            if (t.getRI() != null) {
                if (t.getRI().getColor() == ColorNodo.ROJO && t.getRI().getRI() != null) {
                    if (t.getRI().getRI().getColor() == ColorNodo.ROJO) {
                        g.drawString("e", t.getX() - 15, t.getY() + 15);
                        g.drawString("e1", t.getRI().getX() - 15, t.getRI().getY() + 15);
                        g.drawString("e2", t.getRI().getRI().getX() - 15, t.getRI().getRI().getY() + 15);
                    }

                }
                if (t.getRI().getColor() == ColorNodo.ROJO && t.getRI().getRD() != null) {
                    if (t.getRI().getRD().getColor() == ColorNodo.ROJO) {
                        g.drawString("e", t.getX() - 15, t.getY() + 15);
                        g.drawString("e1", t.getRI().getX() - 15, t.getRI().getY() + 15);
                        g.drawString("e2", t.getRI().getRD().getX() - 15, t.getRI().getRD().getY() + 15);
                    }

                }

            }
        }

    }

    public void pintarSubArbol3(int e) {
        pintarSubArbol3(fondo.getGraphics(), e);
        getGraphics().drawImage(fondo, 0, 0, this);
    }

    private void pintarSubArbol3(Graphics g, int e) {
        Nodo au = buscar(arbol, e);
        g.setColor(Color.YELLOW);
        g.drawLine(au.getX() + 10, au.getY() - 25, au.getX() - 70, au.getY() + 100);
        g.drawLine(au.getX() + 10, au.getY() - 25, au.getX() + 80, au.getY() + 100);
        g.drawLine(au.getX() - 70, au.getY() + 100, au.getX() + 80, au.getY() + 100);
    }

    public Nodo getArbol() {
        return arbol;
    }

    public void setArbol(Nodo arbol) {
        this.arbol = arbol;
    }

    public void limpiar() {
        arbol = null;
        Graphics2D graphics2 = fondo.createGraphics();
        graphics2.setColor(FormUtils.getColorFondo());
        graphics2.fillRect(0, 0, getWidth(), getHeight());
        getGraphics().drawImage(fondo, 0, 0, this);
    }

    public int getIndexRecorrido() {
        return indexRecorrido;
    }

    public void setIndexRecorrido(int indexRecorrido) {
        this.indexRecorrido = indexRecorrido;
    }

}
